package org.ative.chs;

import java.io.*;

import ictk.boardgame.chess.*;
import ictk.boardgame.chess.io.*;
import org.apache.log4j.*;

public class CliPgnAnalyzer {
	public static ChessGame game;
	public static ChessMoveNotation san = new SAN();
	public static ChessMove move;
	public static UciEngine engine;
	public static Logger logger = Logger.getLogger(CliPgnAnalyzer.class.getName());
	
	public static void main(String args[]) {
		
		BasicConfigurator.configure();
		logger.info("Starting pgn analyzer");
		PGNReader pgnReader = null;
		
	    //check the command line args
	    if (args.length != 2) {
	    	logger.error("Wrong number of args. Expect 2, got " + args.length);
	    	System.err.println("usage: java CLIPGNViewer <engine path> <pgn file>");
	    	System.exit(1);
	    }
	    int argIndex = 0;
	    String enginePath = args[argIndex++].trim();
	    String pgnPath = args[argIndex++].trim();
	    
	    File engineFile = new File(enginePath);
	    //check if engine exists
	    if (!engineFile.exists()) { 
	    	logger.error("Failed to find engine. Exiting.");
	    	System.err.println("usage: java CLIPGNViewer <engine path> <pgn file>");
	    	System.exit(1);
	    }
	    
	    File pgnFile = new File(pgnPath);
	    //check if PGN file exists
	    if (!pgnFile.exists()) { 
	    	logger.error("Failed to find PGN file. Exiting.");
	    	System.err.println("usage: java CliPgnAnalyzer <engine path> <pgn file>");
	    	System.exit(1);
	    }
	    
	    try {
	    	// establish the reader object
	    	pgnReader = new PGNReader(new FileReader(pgnFile));
	    	StringBuilder moveStr = new StringBuilder();
	    	// read in the first game in the file
	    	game = (ChessGame) pgnReader.readGame();
	    	// launch engine
	    	engine = new UciEngine(enginePath, 1000);
	    	
	    	BufferedReader bestMoveReader = new BufferedReader(
	    			new InputStreamReader(engine.getBestMoveInputStream()));
	    	AutoReader bestMoveReaderThread = new AutoReader(bestMoveReader);
	    	bestMoveReaderThread.start();
	    	BufferedReader depthReader = new BufferedReader(
	    			new InputStreamReader(engine.getDepthInputStream()));
	    	AutoReader depthReaderThread = new AutoReader(depthReader);
	    	depthReaderThread.start();
	    	BufferedReader npsReader = new BufferedReader(
	    			new InputStreamReader(engine.getNpsInputStream()));
	    	AutoReader npsReaderThread = new AutoReader(npsReader);
	    	npsReaderThread.start();
	    	BufferedReader pvReader = new BufferedReader(
	    			new InputStreamReader(engine.getPvInputStream()));
	    	AutoReader pvReaderThread = new AutoReader(pvReader);
	    	pvReaderThread.start();
	    	BufferedReader currmoveReader = new BufferedReader(
	    			new InputStreamReader(engine.getCurrmoveInputStream()));
	    	AutoReader currmoveReaderThread = new AutoReader(currmoveReader);
	    	currmoveReaderThread.start();
	    	BufferedReader topEvalReader = new BufferedReader(
	    			new InputStreamReader(engine.getTopEvalInputStream()));
	    	AutoReader topEvalReaderThread = new AutoReader(topEvalReader);
	    	topEvalReaderThread.start();
	    	
	    	logger.info("Grabbing game from " + pgnFile);
	    	while (game.getHistory().hasNext()){
	    		move = (ChessMove) game.getHistory().next();
	    		moveStr.append(getUciMove(move) + " ");
	    		engine.setPosition(moveStr.toString());
	    		engine.goInfinite();
		    	Thread.sleep(500);
		    	engine.stop();
		    	
		    	UciBestMove bestMove = engine.getBestMove();
		    	
		    	logger.info("After " + getUciMove(move) + 
		    			" engine thinks " + bestMove.getBestMove());
	    	}
	    	logger.info("Quitting");
	    	bestMoveReader.close();
	    	depthReader.close();
	    	npsReader.close();
	    	pvReader.close();
	    	currmoveReader.close();
	    	topEvalReader.close();
	    	
	    	int engineExit = engine.quit();
	    	pgnReader.close();
	    	logger.debug("Engine exit value: " + engineExit);
	    	logger.info("Done");
	    } catch (Exception e) {
	    	System.out.println(e.getMessage());
	    	logger.error(e.getMessage());
	    	try {
				engine.quit();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				logger.error(e1.getMessage());
			}
	    	System.exit(1);
	    }
	}

	public static String getUciMove(ChessMove move) {
		//logger.debug(move.dump());
		if(move.getPromotion() != null){
			return move.getOrigin().toString() + 
					move.getDestination().toString() + move.getPromotion().toString();
		}
    	return move.getOrigin().toString() + 
    			move.getDestination().toString();
	}
}
